import {
	MessageBox
} from 'element-ui';
export default class bigeMap {
	constructor() {
		this.config
		// this.Dom
		// js和css加载函数
		// this.loading = this.loadingFunc()
		// 当前组件挂载的vue对象
		this.vm
		this.BM
		this.map
		// 当前编辑的对象、id、type
		this.editObj = ''
		this.editObjId = ''
		this.editObjType = ''
		// 自定义添加的数据
		this.customData = new Map()
		// 地图是否经过编辑
		this.isMapEditor = false
	}
	// 初始化地图
	init(vue, Dom) {
		return new Promise((resolve, reject)=>{
			this.vm = vue
			
			this.BM = window.BM
            this.customDataClear()
			if (document.getElementById(Dom)) {
				// console.log(document.getElementById(Dom))
				this.BM.Config.HTTP_URL = this.config.mapUrl;
				// 实例化地图对象
				this.map = this.BM.map(document.getElementById(Dom), null, {
					center: this.config.initialCoordinates,
					minZoom: 1,
					zoom: this.config.zoom,
					maxZoom: this.config.maxZoom,
					zoomControl: true
				});
				//实例化地图图层
				const instantiationMap = this.BM.tileLayer(this.config.mapSource);
				// 将图层添加到地图上
				instantiationMap.addTo(this.map);
				// 循环自定义图层
				this.config.coverage.map(v => {
					//实例化地图图层
					let coverage = this.BM.tileLayer(v);
					coverage.addTo(this.map);
					// console.log(v)
				})
				// console.log(this.config.coverage)
			
			
				if (this.config.isOpenEditor) {
					// 地图打开编辑
					this.openEditorFunc(this.BM, this.map)
				}
				
				resolve(true)
			}
		})
		
	}
    // 清空地图数据
    customDataClear(){
        this.customData.clear()

    }

	// 地图编辑
	openEditorFunc(BM, map) {
		let drawnItems = new BM.FeatureGroup();
		map.addLayer(drawnItems);
		let drawOption = {
			shapeOptions: {
				color: '#FF0000',
				fillColor: '#FF0000',
				weight: 2
			}
		}
		//实例化鼠标绘制的控件
		let drawControl = new BM.Control.Draw({
			position: 'topright', //位置
			//控制绘制的图形
			draw: {
				polyline: drawOption, // 线段
				polygon: drawOption, // 多边形
				rectangle: drawOption, // 矩形
				circle: false, // 圆
				marker: true, // 标注
				circlemarker: false, // 圆点
			},
		});
		map.addControl(drawControl);
		this.drawingFunc(BM, map, drawnItems)

	}
	// 监听绘画完成事件
	drawingFunc(BM, map, drawnItems) {
		map.on(BM.Draw.Event.CREATED, (e) => {
			let type = e.layerType,
				layer = e.layer;
			// 自定义图层数据
			let custom = {
				id: `${type}${new Date().getTime()}`,
				type: type,
				content: '',
				latLng: '',
				options: '',
				isLocation: false
			}
			// 为自定义添加的图层绑定类型和ID
			layer.type = type
			layer.id = `${type}${new Date().getTime()}`
			layer.isLocation = false
			// console.log(type)
			if (type === 'marker') {
				//如果是标注，提示输入标注内容
				MessageBox.prompt('请输入标注内容', '提示', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
				}).then(({
					value
				}) => {
					layer.bindPopup(value);
					custom.content = value
				})
				custom.latLng = layer.getLatLng()
			} else if (type === 'polygon' || type === 'rectangle') {
				// 如果是矩形或者多边形，拿到坐标的方式不一样
				custom.latLng = layer.getLatLngs()[0]
			} else if (type === 'polyline') {
				// 如果是线段
				let style = {
					clickable: true,
					color: "#FF0000",
					fill: false,
					fillColor: "#FF0000",
					fillOpacity: 0.2,
					opacity: 0.5,
					stroke: true,
					weight: 2
				}
				layer.setStyle(style)
				custom.latLng = layer.getLatLngs()
			} else if (type === 'circle') {
				// 如果是圆
				custom.latLng = layer.getLatLng()
			}
			drawnItems.addLayer(layer);
			custom.options = layer.options
			this.customData.set(custom.id, custom)
			this.isMapEditor = true
			// console.log(this.customData)
			this.bindMapClick(layer, map)
		});
		// 绑定按钮事件
		[...document.querySelectorAll('a')].map(v => {
			if (v.className.includes('bigemap-draw-draw')) {
				v.onclick = () => {
					if (this.editObjId) {
						this.cancelEditor()
					}
				}
			}
		})
	}
	// 绑定点击事件
	bindMapClick(layer, map) {
		// 绑定点击事件
		layer.on('click', (e) => {
			this.detectionClick().then(res => {
				if (res) {
					// 删除dom元素
					this.detectionRightClickDom().then(res => {
						let obj = e.target
						// 进入编辑状态
						obj.editing.enable()
						// 绑定当前编辑对象
						this.editObj = obj
						this.editObjId = obj.id
						this.editObjType = obj.type
						const edit = this.customData.get(this.editObjId)
						// 为当前组件页面赋值
						if (obj.type === 'marker') {
							// 如果是标注，则没有options，只有content
							this.vm.editorConfig.content = edit.content
							if (this.config.isOpenFlyToBounds) {
								this.flyTo(edit.latLng, 15)
							}
						} else {
							// 为页面赋值
							this.vm.editorConfig.options.clickable = edit.options.clickable
							this.vm.editorConfig.options.color = edit.options.color
							this.vm.editorConfig.options.fill = edit.options.fill
							this.vm.editorConfig.options.opacity = Number(edit.options
								.opacity)
							this.vm.editorConfig.options.stroke = edit.options.stroke
							this.vm.editorConfig.options.weight = Number(edit.options
								.weight)
							// console.log(edit.options.fillColor)
							if (!edit.options.fill) {
								this.vm.editorConfig.options.fillColor = ''
								this.vm.editorConfig.options.fillOpacity = 0
							} else {
								this.vm.editorConfig.options.fillColor = edit.options
									.fillColor
								this.vm.editorConfig.options.fillOpacity = Number(edit
									.options.fillOpacity)
							}
							if (this.config.isOpenFlyToBounds) {
								this.map.flyToBounds(obj.getBounds());
							}
						}
						this.vm.editorConfig.editorType = edit.type
						this.vm.editorConfig.isLocation = edit.isLocation
						// 打开编辑框
						this.vm.editorBox = true
						// 图形适应地图
					})
				}
			})
		}).on('contextmenu', (e) => {
			// 绑定右击事件
			let obj = e.target
			let latlng = e.containerPoint
			// 如果右击的是当前对象，直接添加右键菜单，如果不是，先退出编辑状态
			if (obj.id === this.editObjId) {
				this.rightClickAddDom(latlng)
			} else {
				this.detectionClick().then(res => {
					if (res) {
						// 绑定当前编辑对象
						this.editObj = obj
						this.editObjId = obj.id
						this.rightClickAddDom(latlng)
						this.vm.editorBox = false
					}
				})
			}
		})
		// 地图右击事件和监听图层编辑
		map.on('contextmenu click', (e) => {
			// this.setEdiorObjIsNull()
			// this.detectionClick()
			// 删除dom元素
			this.detectionRightClickDom()
			// 
			// this.vm.editorBox = false
		}).on(BM.Draw.Event.EDITVERTEX, (e) => {
			// 编辑
			this.changeObjLatLng(e.poly)
		}).on(BM.Draw.Event.EDITMOVE, (e) => {
			// 移动
			this.changeObjLatLng(e.layer)
		}).on(BM.Draw.Event.EDITRESIZE, (e) => {
			// 缩放
			this.changeObjLatLng(e.layer)
		});
	}
	// 改变对象坐标
	changeObjLatLng(layer) {
		let edit = this.customData.get(this.editObjId)
		if (this.editObjType === 'marker') {
			// 标注
			edit.latLng = layer.getLatLng()
		} else if (this.editObjType === 'polyline') {
			// 线段
			edit.latLng = layer.getLatLngs()
		} else if (this.editObjType === 'polygon' || this.editObjType === 'rectangle') {
			// 多边形或者矩形
			edit.latLng = layer.getLatLngs()[0]
		}
		this.isMapEditor = true
	}
	// 右键点击对象，添加删除选项
	rightClickAddDom(latlng) {
		this.detectionRightClickDom().then(res => {
			if (res) {
				const mapPage = document.getElementById("mapPage")
				// 最外层菜单
				const menuBox = document.createElement('div')
				menuBox.className = 'rightClickBox'
				menuBox.id = 'rightClickBox'
				menuBox.setAttribute('style',
					`position: fixed;padding: 5px 10px;background: #FFFFFF;border-radius: 5px;border-radius: 5px;left: ${latlng.x}px;top: ${latlng.y + 10}px;`
				)
				// 菜单箭头
				const span = document.createElement('span')
				span.setAttribute('style',
					`position: absolute;width: 0;height: 0;border: 5px;border-top: 5px solid transparent;border-left: 5px solid transparent;
					border-bottom: 5px solid #FFFFFF;border-right: 5px solid transparent;top: -10px;left: 10px;`
				)
				menuBox.appendChild(span)
				// 菜单按钮层
				const item = document.createElement('div')
				item.className = 'menuItem'
				item.innerText = '删除'
				item.setAttribute('style', 'cursor: pointer;')
				item.onclick = (e) => {
					// 删除元素
					this.editObj.remove()
					// 删除自定义数据
					this.customData.delete(this.editObjId)
					this.setEdiorObjIsNull()
					// 删除dom元素
					this.detectionRightClickDom()
					this.vm.editorBox = false
					this.isMapEditor = true
				}
				menuBox.appendChild(item)
				mapPage.appendChild(menuBox)
			}
		})
	}
	// 完成编辑
	finishEditor(data) {
		let edit = this.customData.get(this.editObjId)
		if (this.editObjType === 'marker') {
			// 标注
			edit.content = data.content
			edit.latLng = this.editObj.getLatLng()
			this.editObj.bindPopup(data.content);
		} else if (this.editObjType === 'polyline') {
			// 线段
			// 替换原始值
			edit.options.clickable = data.options.clickable
			edit.options.color = data.options.color
			edit.options.fill = data.options.fill
			edit.options.opacity = data.options.opacity
			edit.options.stroke = data.options.stroke
			edit.options.weight = data.options.weight
			edit.options.fillColor = data.options.fillColor
			edit.options.fillOpacity = data.options.fillOpacity
			edit.latLng = this.editObj.getLatLngs()
			this.editObj.setStyle(data.options)
		} else if (this.editObjType === 'polygon' || this.editObjType === 'rectangle') {
			// 多边形或者矩形
			// 替换原始值
			edit.options.clickable = data.options.clickable
			edit.options.color = data.options.color
			edit.options.fill = data.options.fill
			edit.options.opacity = data.options.opacity
			edit.options.stroke = data.options.stroke
			edit.options.weight = data.options.weight
			edit.options.fillColor = data.options.fillColor
			edit.options.fillOpacity = data.options.fillOpacity

			edit.latLng = this.editObj.getLatLngs()[0]
			this.editObj.setStyle(data.options)
		}
		// 如果该对象设置了自动定位，其他所有对象全部不定位
		if (data.isLocation) {
			this.customData.forEach(v => {
				if (v.id === this.editObjId && data.isLocation) {
					v.isLocation = data.isLocation
				} else {
					v.isLocation = false
				}
			})
		}
		this.isMapEditor = true
		this.cancelEditor()
	}
	// 取消编辑
	cancelEditor() {
		this.vm.editorBox = false
		this.editObj.editing.disable()
		this.setEdiorObjIsNull()
		// 回到原始状态
		if (this.config.isOpenFlyToBounds) {
			this.flyTo(this.config.initialCoordinates, this.config.zoom)
		}
	}
	// 检测当前是否存在右键菜单
	detectionRightClickDom() {
		return new Promise((reslove, reject) => {
			let clickMenu = document.getElementById('rightClickBox')
			if (clickMenu) {
				try {
					clickMenu.parentNode.removeChild(clickMenu)
					reslove(true)
				} catch (e) {
					//TODO handle the exception
					throw new TypeError('删除dom元素出错', e)
				}
			} else {
				reslove(true)
			}
		})
	}
	// 获取到页面初始数据
	getOriginalData(data) {
		// 接收到原始数据
        this.customDataClear()
		data.forEach(v => {
			this.customData.set(v.id, v)
		})
		if (this.customData.size > 0) {
			this.applyColoursToDrawing()
		}
	}
	// 渲染页面初始数据
	applyColoursToDrawing() {
		// console.log(this.BM)
		this.customData.forEach(v => {
			// 判断数据类型
			switch (v.type) {
				case 'marker':
					// 标注
					let marker = this.BM.marker(v.latLng).addTo(this.map);
					if (v.content !== '') {
						marker.bindPopup(v.content);
					}
					this.originalDataAddFunction(marker, v)
					break;
				case 'polyline':
					// 线段
					let polyline = this.BM.polyline(v.latLng, v.options).addTo(this.map);
					this.originalDataAddFunction(polyline, v)
					break;
				case 'polygon':
					// 多边形
					let polygon = this.BM.polygon(v.latLng, v.options).addTo(this.map);
					this.originalDataAddFunction(polygon, v)
					break;
				case 'rectangle':
					// 多边形
					let rectangle = this.BM.rectangle(v.latLng, v.options).addTo(this.map);
					this.originalDataAddFunction(rectangle, v)
					break;
			}
		})
	}
	// 为原始数据添加事件
	originalDataAddFunction(layer, data) {
		layer.id = data.id
		layer.type = data.type
		layer.isLocation = data.isLocation
		if (data.isLocation) {
			// 让地图适配当前的线段
			if (data.type === 'marker') {
				this.map.flyToBounds([data.latLng]);
			} else {
				this.map.flyToBounds(layer.getBounds());
			}
		}
		if (this.config.isOpenEditor) {
			this.bindMapClick(layer, this.map)
		}
	}
	// 移动地图到指定位置并增加缩放级别
	flyTo(latLng, zoom = 13) {
		this.map.flyTo(latLng, zoom)
	}
	// 检测当前是否存在已有编辑对象
	detectionClick() {
		return new Promise((reslove, reject) => {
			// 编辑相关数据所有不为空时满足条件
			if (this.editObj && this.editObjId && this.editObjType) {
				this.editObj.editing.disable()
				this.setEdiorObjIsNull()
			}
			reslove(true)
		})
	}
	// 设置当前编辑的对象为空
	setEdiorObjIsNull() {
		this.editObj = ''
		this.editObjId = ''
		this.editObjType = ''
	}
	// 完成编辑，上传数据
	postEditor() {
		return new Promise((reslove, reject) => {
			if (this.isMapEditor) {
				reslove([...this.customData.values()])
			} else {
				reject('页面未经过编辑，无需提交数据，可直接返回上一页')
			}
		})
	}
	// 返回上一页
	goBackPage() {
		return new Promise((reslove, reject) => {
			reslove(!this.isMapEditor)
		})
	}
	// 加载地图所需的js和css
	loadingFunc(config) {
		this.config = config
		let url = this.config.mapUrl
		const js = [
			`${url}/bigemap.js/v2.1.0/bigemap.js`,
			`${url}/bigemap-gl.js/v1.1.0/bigemap-gl.js`,
			'./mapEdit/bm.draw.min.js'
		]
		const css = [
			`${url}/bigemap.js/v2.1.0/bigemap.css`,
			`${url}/bigemap-gl.js/v1.1.0/Widgets/widgets.css`,
			'./mapEdit/Bigemap.draw.css'
		]
		return new Promise((reslove, reject) => {
			// 加载css
			let link = css.map(v => {
				let css = document.createElement("link");
				css.rel = "stylesheet";
				css.async = false;
				css.href = v;
				document.head.appendChild(css);
			});
			// 加载js
			let script = js.map(v => {
				let js = document.createElement("script");
				js.type = "text/javascript";
				js.async = false;
				js.src = v;
				document.head.appendChild(js);
				return js;
			});
			let end = script.pop();
			end.onload = reslove;
		})
	}
}
